package com.ssm.common.tool;

import org.springframework.stereotype.Component;

/**
 * Author:      Dante Lee
 * Time:        2015-11-05 09:59 AM
 * Description: 双向加密解密工具
 */
@Component
public class EncryptAndDecrypt {
	
	private static String key = "gesoft9919";

	/**
	 * 加密文本信息
	 * @param content 待加密信息
	 * @return 加密信息结果
	 */
	public String Encrypt(Object content) {
		String encrypt = "";
		try {
			encrypt = setParameter(content.toString(), key);
		} catch (Exception e) {
			encrypt = content.toString();
		}
		return encrypt;
	}

	public String Dncrypt(Object content) {
		String dncrypt = "";
		try {
			dncrypt = getParameter(content.toString(), key);
		} catch (Exception e) {
			dncrypt = content.toString();
		}
		return dncrypt;
	}

	/**
	 * 设置参数变量（对参数信息进行加密处理）
	 * @param content 待加密信息
	 * @param key 加密串
	 * @return 加密信息结果
	 * @throws Exception 捕获异常
	 */
	private static String setParameter(String content, String key) throws Exception {
		if (content.equals(""))
			return "";
		String strResult = "";
		strResult = encryptContent(content, key).toUpperCase();
		return strResult;
	}

	/**
	 * 加密信息（异或方式）
	 * @param content
	 * @param desKey
	 * @return
	 */
	private static String encryptContent(String content, String desKey) throws Exception {
		String strResult = "";
		byte[] byt = content.getBytes();
		byte[] bytDes = lockChar(byt, byt.length, desKey);
		strResult = byte2hex(bytDes);
		return strResult;
	}

	/**
	 * 加密
	 * @param byText byte[]要加密的字节组
	 * @param iTextLen int字节组中字节数
	 * @param strPass String密钥
	 * @return byte[]加密后的字节组
	 */
	private static byte[] lockChar(byte[] byText, int iTextLen, String strPass) throws Exception {
		int nLenght = strPass.length();
		for (int j = 0; j < iTextLen; j++) {
			for (int i = 0; i < nLenght; i++) {
				int iByText = byText[j];
				int iPass = strPass.charAt(i);
				iByText = iByText ^ iPass;
				byText[j] = (byte) iByText;
			}
		}
		return byText;
	}

	/**
	 * 2进制字节转16进制字符串
	 * @param b 2进制字节
	 * @return 16进制字符串，用:间隔
	 */
	protected static String byte2hex(byte[] b) throws Exception {
		StringBuffer hs = new StringBuffer();
		String stmp = "";
		for (int n = 0; n < b.length; n++) {
			stmp = Integer.toHexString(b[n] & 0XFF);
			if (stmp.length() == 1)
				hs.append("0").append(stmp);
			else
				hs.append(stmp);
		}
		return hs.toString();
	}

	/**
	 * 得到参数变量值（加密信息提取）
	 * @return
	 * @throws Exception
	 */
	private static String getParameter(String content, String key) throws Exception {
		if (content.equals(""))
			return "";
		String strDesContent = decryptKey(content.toLowerCase(), key);
		return strDesContent;
	}

	/**
	 * 解密 key 信息
	 * @param content
	 * @return
	 * @throws Exception
	 */
	private static String decryptKey(String content, String key) throws Exception {
		byte[] bContent = hex2byte(content);
		byte[] bDesKey = key.getBytes();
		String strDesContent = decryptContent(bContent, bDesKey);
		return strDesContent;
	}

	/**
	 * 16进制转2进制字节
	 * @param str 16进制字符串，用:间隔
	 * @return 2进制字节
	 */
	protected static byte[] hex2byte(String str) throws Exception {
		int length = str.length() / 2;
		byte bt[] = new byte[length];
		for (int n = 0; n < length; n++)
			bt[n] = (byte) Integer.parseInt(str.substring(2 * n, 2 * (n + 1)), 16);
		return bt;
	}

	/**
	 * 信息（异或方式）
	 * @param strContent String 加密文件
	 * @param strDesKey String 加密码
	 * @return String 加密结果
	 * @throws Exception
	 */
	private static String decryptContent(byte[] content, byte[] desKey) throws Exception {
		String strResult = "";
		String strDesKey = new String(desKey);
		byte[] bytDes = unLockChar(content, content.length, strDesKey);
		strResult = new String(bytDes, "GBK");
		return strResult;
	}

	/**
	 * 解密
	 * @param byText byte[]要解密的字节组
	 * @param iTextLen int字节组中字节数
	 * @param strPass String密钥
	 * @return byte[]解密后的字节组
	 */
	private static byte[] unLockChar(byte[] byText, int iTextLen, String strPass) throws Exception {
		int nLenght = strPass.length();
		for (int j = 0; j < iTextLen; j++) {
			for (int i = 0; i < nLenght; i++) {
				int iByText = byText[j];
				int iPass = strPass.charAt(i);
				iByText = iByText ^ iPass;
				byText[j] = (byte) iByText;
			}
		}
		return byText;
	}
	
	public static void main(String[] args) {
		EncryptAndDecrypt e = new EncryptAndDecrypt();
		System.out.println(e.Dncrypt("3C30373236393535353132372A3537343636333337353D"));
	}
	
}